// %%%%%%%%%%%%%%%%%%%%%%% HILO_CONTEXT.H %%%%%%%%%%%%%%%%%%%%%%%
// Provides an Python interface with the WINAPI's CONTEXT structure.
// This file does not take care of initializing this type into the module.
//		Only provides access to definitions; to add to the module, call hilo_CINT::Define().
// --------------------------------------------------------------

#ifndef _HILO_CONTEXT_H_
#define _HILO_CONTEXT_H_

#include "globals.h"

#include <Windows.h>
#include <Python.h>
#include <structmember.h>

#pragma once

//
// A Python object containing a thread CONTEXT.
//

struct hilo_CONTEXT {
	PyObject_HEAD
	CONTEXT cContext;
};

//
// Wraps functionality and data for the Python object into a class containing no instance methods.
// Provides conversion between C's CONTEXT and Python's hilo_CONTEXT objects.
//

class hilo_CINT {
public:

	//
	// The members of the CONTEXT object we are making available.
	// These includes some control registers and all the integer registers.
	// We assume we are building on x86-32.
	//

	static PyMemberDef members[];

	//
	// No methods defined for a CONTEXT object; purely for storage.
	//

	static PyMethodDef methods[];

	//
	// The definition of this object's type.
	//

	static PyTypeObject type;

	//
	// Defines a CONTEXT object for the module given.
	//

	__inline static void define( PyObject * );

	//
	// Returns a pointer to a hilo_CONTEXT object from the given CONTEXT structure.
	//

	__inline static PyObject* fromContext( CONTEXT * );

	//
	// Sets the state of the CONTEXT given to that of the hilo_CONTEXT object.
	//

	__inline static void toContext( hilo_CONTEXT*, CONTEXT* );
};

__inline void hilo_CINT::define( PyObject * module ) {
	hilo_CINT::type.tp_new = PyType_GenericNew;
	if (PyType_Ready(&hilo_CINT::type) < 0)
		return;

	Py_INCREF(&hilo_CINT::type);
	PyModule_AddObject(module, "CONTEXT", (PyObject*)&hilo_CINT::type);
}

__inline PyObject* hilo_CINT::fromContext( CONTEXT *cContext ) {
	hilo_CONTEXT *self;
	self = (hilo_CONTEXT*)(&hilo_CINT::type)->tp_alloc(&hilo_CINT::type, 0);
	self->cContext = *cContext;
    return (PyObject*)self;
}

__inline void hilo_CINT::toContext( hilo_CONTEXT* hContext, CONTEXT* cContext ) {
	*cContext = hContext->cContext;
}

#endif